package com.ruoyi.workflow.service.impl;

import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.workflow.domain.WfCopy;
import com.ruoyi.workflow.domain.WfCopyDraft;
import com.ruoyi.workflow.domain.WfCopyTable;
import com.ruoyi.workflow.domain.bo.WfTaskBo;
import com.ruoyi.workflow.domain.dto.WfCopyListInput;
import com.ruoyi.workflow.domain.dto.WfCopyView;
import com.ruoyi.workflow.service.IWfCopyService;
import lombok.RequiredArgsConstructor;
import org.babyfish.jimmer.Page;
import org.babyfish.jimmer.sql.JSqlClient;
import org.babyfish.jimmer.sql.ast.mutation.SaveMode;
import org.flowable.engine.HistoryService;
import org.flowable.engine.history.HistoricProcessInstance;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * 流程抄送Service业务层处理
 *
 * @author KonBAI
 * @date 2022-05-19
 */

@Service
@RequiredArgsConstructor
public class WfCopyServiceImpl implements IWfCopyService {

    private final HistoryService historyService;
    private final JSqlClient sqlClient;

    /**
     * 查询流程抄送
     *
     * @param copyId 流程抄送主键
     * @return 流程抄送
     */

    @Override
    public WfCopyView queryById(Long copyId) {
        return sqlClient.findById(WfCopyView.class, copyId);
    }

/**
 * 查询流程抄送列表
 *
 * @param bo 流程抄送
 * @return 流程抄送
 */

    @Override
    public Page<WfCopyView> selectPageList(WfCopyListInput bo, PageQuery pageQuery) {
        WfCopyTable table = WfCopyTable.$;
        return sqlClient.createQuery(table)
                .where(
                        table.userId().eqIf(bo.getUserId()),
                        table.processName().ilikeIf(bo.getProcessName()),
                        table.originatorName().ilikeIf(bo.getOriginatorName())
                ).select(table.fetch(WfCopyView.class))
                .fetchPage(pageQuery.getPageNum(), pageQuery.getPageSize());
    }


    /**
     * 查询流程抄送列表
     *
     * @param bo 流程抄送
     * @return 流程抄送
     */

    @Override
    public List<WfCopyView> selectList(WfCopyListInput bo) {
        WfCopyTable table = WfCopyTable.$;
        return sqlClient.createQuery(table)
                .where(
                        table.userId().eqIf(bo.getUserId()),
                        table.processName().ilikeIf(bo.getProcessName()),
                        table.originatorName().ilikeIf(bo.getOriginatorName())
                ).select(table.fetch(WfCopyView.class))
                .execute();
    }

    @Override
    public Boolean makeCopy(WfTaskBo taskBo) {
        if (StringUtils.isBlank(taskBo.getCopyUserIds())) {
            // 若抄送用户为空，则不需要处理，返回成功
            return true;
        }
        HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery()
                .processInstanceId(taskBo.getProcInsId()).singleResult();
        String[] ids = taskBo.getCopyUserIds().split(",");
        List<WfCopy> copyList = new ArrayList<>(ids.length);
        String originatorId = SecurityUtils.getUserId();
        String originatorName = SecurityUtils.getLoginUser().getUser().getNickName();
        String title = historicProcessInstance.getProcessDefinitionName() + "-" + taskBo.getTaskName();
        for (String userId : ids) {
            WfCopy wfCopy = WfCopyDraft.$.produce(copy -> {
                copy.setTitle(title);
                copy.setProcessId(historicProcessInstance.getProcessDefinitionId());
                copy.setProcessName(historicProcessInstance.getProcessDefinitionName());
                copy.setDeploymentId(historicProcessInstance.getDeploymentId());
                copy.setInstanceId(taskBo.getProcInsId());
                copy.setTaskId(taskBo.getTaskId());
                copy.setUserId(userId);
                copy.setOriginatorId(originatorId);
                copy.setOriginatorName(originatorName);
            });
            copyList.add(wfCopy);
        }
        return sqlClient.saveEntitiesCommand(copyList)
                .setMode(SaveMode.INSERT_ONLY)
                .execute().getTotalAffectedRowCount() > 0;
    }

}

